perm filename PAREN[E,ALS] blob sn#193111 filedate 1975-12-19 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00002 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	PARSAV PARL PARR PAR PARFND PARB PAREXT PARRCD PARNUL
C00020 ENDMK
C⊗;
;PARSAV PARL PARR PAR PARFND PARB PAREXT PARRCD PARNUL

IMPURE
LEFTC:	"("		;Left-symbol
RITEC:	")"		;Right symbol
PARMAX:	77777		;Desired maximum level
PARMIN:	-77777		;Desired minimum level
PARGDP:	0		;Greatest level
PARLDP:	0		;Lowest level
PARTMS:	0		;Times at max. level
PARTML:	0		;Times at min. level
PARCT:	0		;Character count on line being studied
PARLN:	0		;Line count when found
PARDEF:	0		;Deficiency
PARPRS:	0		;Pairs of bracketing symbols
PARTOT:	0		;Total character count
PARCUR:	0		;Value of CURGAG when command was given
PARARR:	0		;Value of ARRL when command was given
PAROFF:	0		;Value of EDCNM when command was given
PARX:	0		;Flag for Xtend command
PURE

comment ⊗
Register assignment

Register	Contents
A		Initial argument, then pointer
B		Character count
C		Character
D		Current level
E		Temporary ARRLIN for line being searched
G		Times at minimum depth
H		Flags for special characters
I		Least level
DSP		Dispatch table address
Q		Line count
T		Left symbol count
TT		Times at greatest depth
	end of comment ⊗

;To save current position
PARSAV:	TRNE F,EDITM
	PUSHJ P,FNEDIT
	MOVE E,CURPAG		;Save data needed by ↔ command to return
	MOVEM E,PARCUR
	MOVE E,ARRL
	MOVEM E,PARARR
	MOVE E,EDCNM
	TRNN F,EDITM
	SETZ E,
	MOVEM E,PAROFF
	POPJ P,

;Right parenthesis search
RPAREN:	SETOM PARX		;Set extend flag
	SKIPA
PARR:	SETZM PARX
	MOVE C,LEFTC		;Is this a special case with
	CAMN C,RITEC		;the left-symbol the same as the right-symbol?
	JRST PARL2		;All searches are for left symbols in this case
	MOVEM A,PARMIN		;Testing for a desired minimum
	MOVEI Q,77777		;To prevent exit on left-symbols
	MOVEM Q,PARMAX
	SOS PARMIN		;Test is made after the symbol instead of before
	JRST PAR

;Left parenthesis search
LPAREN:	SETOM PARX		;Set extend flag
	SKIPA
PARL:	SETZM PARX
PARL2:	MOVEM A,PARMAX		;Testing for a desired maximum
	MOVNI Q,77777
	MOVEM Q,PARMIN		;To prevent exit on right-symbols
PAR:	MOVEM A,SARG		;Save argument for reporting
	PUSHJ P,PARSAV		;To save present conditions
	MOVE E,CURPAG
	MOVEM E,SRCPG		;Will be updated as multi-page search progresses
	SETZM TYOPNT
	HRRZ E,ARRLIN		;Get line location in free storage
	MOVEI A,LLDESC(E)
	TLO A,440700
	MOVEI DSP,PARDSP	;Dispatch table address for displayed page
	MOVSI H,NSPEC!LSPC	;Set flags for special characters
	SETZB B,PARTOT		;Characters on line, total characters
	SETZB TT,PARGDP		;Number of times at greatest level, this level
	SETZB G,PARLDP		;Minimum level count,lowest level
	SETZB T,D		;Left-symbol count, current level
	SETZ Q,
	MOVEI I,77777		;Minimum level after reaching desired at right-sym.
	TRNN F,EDITM		;In line edit mode?
	JRST PAR1		;No
	MOVE B,EDCNM		;So positioning will be right in first line
	MOVNM B,PARTOT		;but will not count in characters searched
	MOVE G,EDPOS		;Get location of cursor
	ADD G,EDTBS		;TAB's were not counted in EDPOS
	ADD G,EDTBS		;and they are duplicated
	JUMPE G,PAR0		;It could be at the start
	IBP A			;We want A to point to starting position
	SOJG G,.-1
PAR0:	SETZB G,PARGDP 		;Minimum level count,greatest level
	SETZM PARLDP		;Minimum level
	ILDB C,A		;Look at new first character
	CAME C,RITEC		;Are we under a right-symbol?
	JRST PAR1B		;We are not, so consider this character
	AOJA B,PAR1		;We are, so count and read another character

;Dispatch table for in-core PAREN search
PARDSP:	JRST PARCR		;null	we should never get here
	AOJA B,PAR1		;BS	we should never get here
	JRST PARCR		;CR
	JRST PARCR		;LF	treat as missing CR
	JRST PAR1A		;TAB	special treatment on displayed page
	AOJA B,PAR1		;ALT	should not be in text
	JFCL			;FF	should not be in text

;Dispatch table for extend PAREN search
PAXDSP:	JRST PARNUL		;null	
	JRST PARRCD		;177	Normal end of buffer signal
	AOJA Q,PARXCR		;CR
	AOJA Q,PARXCR		;LF	treat as missing CR
	AOJA B,PAR1		;TAB	as any other char.
	AOJA B,PAR1		;ALT
	JRST PARFF		;FF

;Dispatch table for Xtent CR
PACDSP:	JRST PARXC2		;Null	pass it on after resetting DSP
	JRST PARRCD		;177	End of buffer just after a CR
	AOJA Q,PARXC1		;CR	count it and still look for a LF
	JRST [ILDB C,A
	      JRST PARXC2]	;LF	eat it and reset DSP
	JRST PARXC2		;TAB	pass it on
	JRST PARXC2		;ALT	pass it on
	JRST PARXC2		;FF	pass it on

;Test for ESC I interruption
PARFF:	SKIPN ESCIEN
	JRST PARFF2		;No interruption
PARESC:	SETOM ESCI2		;An ESC I interruption
	MOVE T,[PUSHJ P,UUOH]
	MOVEM T,41
	XCT SRCDP3		;Clear search page number if on III.
	PUSHJ P,ABCRLF		;Type CRLF (clobbers T).
	OUTSTR [ASCIZ / ESC I termination at end of page /]
	SETZM TYOPNT
	TYPDEC SRCPG
	JRST PAREXX		;Treat as any not found

;Code to update page count and display it after the second page
;on finding a FF in the text at any point
PARFF2:	ADDM B,PARTOT		;Accumulate line count
	SETZB B,Q		;and reset B and Q
	PUSHJ P,SRCFPP		;Add to page count and display number
	JRST PAR1

PARXCR:	MOVEI DSP,PACDSP	;Special dispatch in this case
	ADDM B,PARTOT		;Add to total character count
	SETZ B,			;and start over
PARXC1:	ILDB C,A		;We must look at the next character
	TDNE C,CTAB(C)
	XCT @CTAB(C)
PARXC2:	MOVEI DSP,PAXDSP	;Reset dispatch index
	JRST PAR1B		;Already have next character
	
PAR1X:	AOS IBLK
	CAME DSP,[PACDSP]	;See where we came from
	JRST PAR1		;Normal return from new buffer load
	JRST PARXC1		;Must still look for a LF

PARCR:	HRRZ E,(E)		;go to the next line of text
	CAIN E,BOTSTR		;Are we at the end of the page?
	JRST PAREX		;Yes
	MOVEI A,LLDESC(E)
	TLO A,440700
	AOJ Q,			;Add to line count
	ADDM B,PARTOT		;Add to total character count
	SETZ B,			;Start count over
;Start of inner loop. Used for both displayed-page search and extended search
;DSP set to PARDSP, PAXDSP or PACDSP depending on circumstances
PAR1:	ILDB C,A
PAR1B:	TDNE H,CTAB(C)
	XCT @CTAB(C)
	CAMN C,LEFTC		;Are we at a LEFT-SYMBOL?
    	AOJA D,PAR2		;Yes
	CAMN C,RITEC		;Are we at a RIGHT-SYMBOL?
	SOJA D,PAR2A		;Yes
	AOJA B,PAR1		;Go around again
;End of inner loop

;We've found a TAB (on the displayed page)
PAR1A:	ILDB C,A
	CAIE C,11
	JRST .-2		;Eat to next TAB
	AOJA B,PAR1

;We've found a left-symbol
PAR2:	AOJ T,			;Count as start of another pair
	AOJ I,			;The old minimum no longer holds
	CAMGE D,PARGDP		;Are we at less than the maximum level?
	AOJA B,PAR1		;Yes, so go to next character
	CAMG D,PARGDP		;Have we been to this level before?
	AOJA TT,PAR3		;Yes, so add to count of number of times here
	MOVEI TT,1		;Start the count for number of times at this level
	AOS PARGDP			;And add to the maximum level
	CAML D,PARMAX		;Are we at the desired level?
	JRST PARFND		;Yes
PAR3:	AOJA B,PAR1		;Go to next character

;We've found a right-symbol
PAR2A:	CAMLE D,PARGDP		;Are we at greater than the minimum level?
	JRST PAR2B		;Yes
	CAML D,PARGDP		;Have we been at this level before?
	AOJA G,PAR2B		;Yes, so add to count
	MOVEI G,1		;Start the count for this new level
	SOS PARGDP		;and subtract from the minimum level
PAR2B:	CAMGE D,PARMIN
	AOJA B,PAR1
	CAMGE D,I
	MOVEM D,I
	CAME D,PARMIN
	AOJA B,PAR1
;We've found the desired right-symbol
PARFND:	SETZM PARDEF
	MOVNS PARLDP		;Negative of minimum level encountered
	MOVEM G,PARTML		;Times at this level
PARNOT:	MOVEM T,PARPRS		;Number of left-symbols found
	MOVEM TT,PARTMS		;Times at this level
	MOVEM B,PARCT
	ADDM B,PARTOT
	MOVEM Q,PARLN		;Free register
	SKIPE PARDEF
	JRST PARTYP
	MOVE A,SRCPG		;Desired page
	CAME A,CURPAG
	PUSHJ P,NEWPG0
PARTYP:	OUTSTR [ASCIZ /
Sought	Found	#Lefts	Max.L	#	Min. L	#	Chars.	Deficiency
  /]
	MOVE Q,PARMAX
	CAIL Q,77777			;What were we looking for?
	JRST PARTY1			;A right-symbol
	MOVE C,LEFTC			;Report the left-symbol
	TYPCHR (C)			;before the argument
	TYPDEC SARG
	JRST PARTY3

PARTY1:	MOVE C,RITEC			;Report the right-symbol
	TYPDEC SARG			;after the argument
	TYPCHR (C)
PARTY3:	SKIPE PARDEF
	OUTSTR [ASCIZ/	No	/]
	SKIPN PARDEF
	OUTSTR [ASCIZ /	Yes	/]
	TYPDEC PARPRS
	OUTSTR [ASCIZ /	/]
	TYPDEC PARGDP
	OUTSTR [ASCIZ /	/]
	TYPDEC PARTMS
	OUTSTR [ASCIZ /	/]
	SKIPE PARLDP
	TYPCHR "-"
	TYPDEC PARLDP
	OUTSTR [ASCIZ /	/]
	TYPDEC PARTML
	OUTSTR [ASCIZ /	/]
	TYPDEC PARTOT
	OUTSTR [ASCIZ /	/]
	SKIPN PARDEF		;Were we successful?
	JRST PARTY2		;Yes
	SKIPL PARDEF
	JRST .+3
	TYPCHR "↓"
	MOVNS PARDEF
	TYPDEC PARDEF
	TRNN F,EDITM
	JRST PPJ1CR		;Not from line editor--put out CRLF and skip return.
	JRST REEDT2		;Don't say HUH

PARTY2:	OUTSTR [ASCIZ /	/]
	MOVE A,PARLN		;MOVARR wants line count in A
	PUSHJ P,MOVARR		;Get to correct line
	SKIPN DPY
	JRST PPJ1CR		;No line editor--put out CRLF and take skip return.
	PUSH P,PARCT
	PUSH P,[240]
	JRST EDIT1

PARERR:	OUTSTR [ASCIZ /Something is wrong with this file/]
	JRST PAREXX

PAREX:	SKIPGE PARX		;Is this an EXTENT case
	JRST PAREXT		;Yes, we must now search the other pages
PAREXX:	MOVNS PARLDP		;Negative of minimum level encountered
	MOVEM G,PARTML		;Times at this level
	MOVE Q,PARMAX
	CAIL Q,77777
	JRST PAREX2		;We were looking for a right-symbol
	MOVE G,PARMAX
	SUB G,PARGDP
	MOVEM G,PARDEF
	JRST PARNOT

PAREX2:	MOVE G,PARGDP
	CAMG G,PARMIN		;Did we ever reach the desired level
	JRST PAREX3		;No
	SUB I,PARMIN		;Yes, but how far did we miss getting back?
	MOVEM I,PARDEF
	JRST PARNOT

PAREX3:	MOVE G,PARGDP
	SUB G,PARMIN
	SOJ G,
	MOVEM G,PARDEF
	JRST PARNOT

;This code puts you back from whence you came on the last (, ) or ↔ command
PARB:	PUSH P,PAROFF
	PUSH P,PARARR
	PUSH P,PARCUR
	PUSHJ P,PARSAV		;So we can get back here
	POP P,A
	CAME A,CURPAG
	PUSHJ P,NEWPG0
	SETZM TYOPNT
	OUTSTR [ASCIZ /
Back you go fron page /]
	TYPDEC PARCUR
	OUTSTR [ASCIZ /, line /]
	TYPDEC PARARR
	OUTSTR [ASCIZ /, char. /]
	TYPDEC PAROFF
	POP P,A
	SUB A,ARRL		;Just in case we are not at 0
	PUSHJ P,MOVARR
	SKIPN DPY
	JRST PPJ1CR		;No line editor--put out CRLF and take skip return.
	PUSH P,[240]
	JRST EDIT1

;To get next block on finishing the displayed page
PAREXT:	SKIPE ESCIEN
	JRST PARESC
	MOVE A,DIRPT
	HRRZ C,(A)
	CAMN C,DIREND
	JRST PAREXX		;There are no more pages
	SKIPN A,1(C)
	JRST PARERR
	MOVEI DSP,PAXDSP	;Set DSP for EXTEND search
	SETZB B,Q
	HRRZ C,A
	PUSHJ P,SRCFPP		;Updata page number and display
	ANDCMI A,-1
	ROT A,7
	ADD A,IBFPNT
	IBP A
	CAMN C,IBLK		;Don't USETI if already there
	JRST PAR1
PAREXZ:	XCT %SETI
	MOVEM C,IBLK
	JRST PARRC2

;Reload when buffer is exhausted
PARRCD:	SKIPLE PARX
	JRST PAREXX		;Not found
	MOVE A,[440700,,IBUF]
;	AOS IBLK
PARRC2:	XCT %IN
	JRST PAR1X		;Continue after testing if previous char. was a CR
	XCT %STAT
	TRNN C,20000		;EOF?
	JRST PARERR		;No, lose
	MOVE C,IBLK
	LSH C,7			;Number of words successfully read
	CAML C,FILWC		;Beyond EOF already?
	JRST PARERR		;Lose
	SUB C,FILWC		;Negative of number of real words in last buffer
	MOVN C,C
	SETZM IBUF(C)		;Fill rest of buffer with nulls
	MOVEI C,IBUF+1(C)
	HRLI C,-1(C)		;pointer to BLT rest of buffer with nulls
	CAME C,[IBUF+177,,IBUF+200]	;Don't do BLT if only one word left
	BLT C,IBUF+177
	MOVEI C,777
	MOVEM C,PARX		;Flag for no more text
	JRST PAR1X		;Continue after test

;Fast handling of words full of nulls
PARNUL:	CAMGE A,[100700,,0]	;Is the null at the end of a word?
	SKIPE 1(A)		;Is next word all nulls?
	JRST PAR1		;No
	AOJA A,.-2		;Yes, so try with the next word